package nm_core

import (
	"fmt"
	"os"
	"path/filepath"
	"time"

	"gitee.com/war2001/NiuMaEasyGo/global"
	"go.uber.org/zap"
	"go.uber.org/zap/zapcore"
	"gopkg.in/natefinch/lumberjack.v2"
)

// Zap 获取 zap.Logger
func Zap() (logger *zap.Logger) {
	if ok, _ := pathExists(global.Config.Log.Path); !ok { // 判断是否有Director文件夹
		fmt.Printf("create %v directory\n", global.Config.Log.Path)
		_ = os.Mkdir(global.Config.Log.Path, os.ModePerm)
	}

	// 获取当前日期作为日志目录名
	now := time.Now()
	logDir := filepath.Join("logs", fmt.Sprintf("%d%02d%02d", now.Year(), now.Month(), now.Day()))

	// 确保日志目录存在
	if err := os.MkdirAll(logDir, 0755); err != nil {
		panic("创建日志目录失败: " + err.Error())
	}

	// 设置日志级别
	var level zapcore.Level
	switch global.Config.Log.Level {
	case "debug":
		level = zap.DebugLevel
	case "info":
		level = zap.InfoLevel
	case "warn":
		level = zap.WarnLevel
	case "error":
		level = zap.ErrorLevel
	default:
		level = zap.InfoLevel
	}

	// 错误日志配置
	errorLogConfig := &lumberjack.Logger{
		Filename:   filepath.Join(logDir, "err.log"),
		MaxSize:    global.Config.Log.MaxSize,
		MaxBackups: global.Config.Log.MaxBackups,
		MaxAge:     global.Config.Log.MaxAge,
		Compress:   global.Config.Log.Compress,
	}

	// 信息日志配置
	infoLogConfig := &lumberjack.Logger{
		Filename:   filepath.Join(logDir, "info.log"),
		MaxSize:    global.Config.Log.MaxSize,
		MaxBackups: global.Config.Log.MaxBackups,
		MaxAge:     global.Config.Log.MaxAge,
		Compress:   global.Config.Log.Compress,
	}

	// 设置日志编码器
	encoderConfig := zapcore.EncoderConfig{
		TimeKey:        "time",
		LevelKey:       "level",
		NameKey:        "logger",
		CallerKey:      "caller",
		FunctionKey:    "function",
		MessageKey:     "msg",
		StacktraceKey:  "stacktrace",
		LineEnding:     zapcore.DefaultLineEnding,
		EncodeLevel:    zapcore.LowercaseLevelEncoder,
		EncodeTime:     zapcore.ISO8601TimeEncoder,
		EncodeDuration: zapcore.SecondsDurationEncoder,
		EncodeCaller:   zapcore.ShortCallerEncoder,
	}

	// 设置彩色日志
	if global.Config.Log.EnableColor {
		encoderConfig.EncodeLevel = zapcore.LowercaseColorLevelEncoder
	}

	// 创建核心
	var cores []zapcore.Core

	// 错误日志核心（只记录error及以上级别）
	errorCore := zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderConfig),
		zapcore.AddSync(errorLogConfig),
		zap.ErrorLevel,
	)
	cores = append(cores, errorCore)

	// 信息日志核心（记录info及以上，但不包含error）
	infoCore := zapcore.NewCore(
		zapcore.NewJSONEncoder(encoderConfig),
		zapcore.AddSync(infoLogConfig),
		zap.LevelEnablerFunc(func(lvl zapcore.Level) bool {
			return lvl >= level && lvl < zap.ErrorLevel
		}),
	)
	cores = append(cores, infoCore)

	// 如果启用控制台输出
	if global.Config.Log.EnableConsole {
		consoleEncoder := zapcore.NewConsoleEncoder(encoderConfig)
		consoleCore := zapcore.NewCore(
			consoleEncoder,
			zapcore.AddSync(os.Stdout),
			level,
		)
		cores = append(cores, consoleCore)
	}

	// 创建日志对象
	core := zapcore.NewTee(cores...)
	logger = zap.New(core, zap.AddCaller())

	if global.Config.Log.EnableCaller {
		logger = logger.WithOptions(zap.AddCallerSkip(1))
	}

	return logger
}

// pathExists 判断路径是否存在
func pathExists(path string) (bool, error) {
	_, err := os.Stat(path)
	if err == nil {
		return true, nil
	}
	if os.IsNotExist(err) {
		return false, nil
	}
	return false, err
}
